package com.xxxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxxy.dao.*;
import com.xxxy.model.*;
import com.xxxy.redis.service.RedisService;
import com.xxxy.response.ReviewedPaperProgressResponse;
import com.xxxy.response.ReviewedQuestionListResponse;
import com.xxxy.response.ReviewedQuestionProgressResponse;
import com.xxxy.service.ReviewedService;
import lombok.Data;
import org.apache.tomcat.util.buf.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author StevenShen
 * @date 2022/3/8 10:42
 */
@Service
@EnableScheduling
public class ReviewedServiceImpl extends ServiceImpl<ReviewedDao, Reviewed> implements ReviewedService {

    @Autowired
    private ExaminationPaperDao examinationPaperDao;

    @Autowired
    private QuestionDao questionDao;

    @Autowired
    private StudentAnswerDao studentAnswerDao;

    @Autowired
    private ReviewedDao reviewedDao;

    @Autowired
    private TeacherReviewedDao teacherReviewedDao;

    @Autowired
    private RedisService redisService;

    @Override
    public Boolean startReviewed(Integer examinationPaperId) {

        ExaminationPaper examinationPaper = null;
        Reviewed reviewed = null;

        if (examinationPaperId != null) {
            examinationPaper = examinationPaperDao.selectById(examinationPaperId);
            if (examinationPaper != null) {
                reviewed = new Reviewed();
                reviewed.setPaperId(examinationPaperId);
            } else {
                return false;
            }
        } else {
            return false;
        }

        String questions = examinationPaper.getQuestions();
        String[] questionArray = questions.split(",");
        String section = examinationPaper.getSection();
        String[] sectionArray = section.split(",");
        String sectionScore = examinationPaper.getSectionScore();
        String[] sectionScoreArray = sectionScore.split(",");

        for (int i = 0; i < questionArray.length; i++) {
            if (Objects.equals(questionDao.selectById(Integer.parseInt(questionArray[i])).getType(), 3)) {
                reviewed.setQuestionId(Integer.parseInt(questionArray[i]));
                reviewed.setQuestionIndex(i);

                for (int j = 0; j < sectionArray.length; j++) {
                    if (i < Integer.parseInt(sectionArray[j])) {
                        reviewed.setFullScore(Double.parseDouble(sectionScoreArray[j]));
                        break;
                    }
                }

                QueryWrapper<StudentAnswer> wrapper = new QueryWrapper<>();
                wrapper.eq("examination_paper_id", examinationPaperId);
                List<StudentAnswer> studentAnswers = studentAnswerDao.selectList(wrapper);
                String[] reviewedStudent = new String[studentAnswers.size()];
                String[] studentStatus = new String[studentAnswers.size()];
                for (int j = 0; j < studentAnswers.size(); j++) {
                    reviewedStudent[j] = String.valueOf(studentAnswers.get(j).getId());
                    studentStatus[j] = "0";
                }
                String reviewedStudents = StringUtils.join(Arrays.asList(reviewedStudent), ',');
                String studentStatuses = StringUtils.join(Arrays.asList(studentStatus), ',');
                reviewed.setReviewedStudent(reviewedStudents);
                reviewed.setStudentStatus(studentStatuses);

                reviewedDao.insert(reviewed);
            }
        }

        return true;
    }

    @Override
    public List<ReviewedQuestionListResponse> getQuestionList(Integer examinationPaperId) {

        QueryWrapper<Reviewed> wrapper = new QueryWrapper<>();
        wrapper.eq("paper_id", examinationPaperId);
        List<Reviewed> reviewedList = reviewedDao.selectList(wrapper);

        List<ReviewedQuestionListResponse> questionList = new ArrayList<>();
        for (Reviewed reviewed : reviewedList) {
            ReviewedQuestionListResponse question = new ReviewedQuestionListResponse();
            question.setQuestionIndex(reviewed.getQuestionIndex());
            question.setTeachers(teacherReviewedDao.getTeachers(examinationPaperId, reviewed.getQuestionIndex()));
            question.setFullScore(reviewed.getFullScore());
            question.setQuestionId(reviewed.getQuestionId());
            questionList.add(question);
        }

        return questionList;
    }

    @Override
    public List<ReviewedQuestionProgressResponse> getQuestionProgress(Integer examinationPaperId) {

        // 获取该试卷的进度信息
        List<ReviewedQuestionProgress> list = (List<ReviewedQuestionProgress>) redisService.get(String.valueOf(examinationPaperId));

        // 阅卷进度
        Double reviewedProgress = null;
        // 阅卷速度（题每小时）
        Long reviewedSpeed = null;
        // 预计完成时间
        Date estimatedTime = null;

        // 获取所有试题的进度
        List<ReviewedQuestionProgressResponse> reviewedQuestionProgressList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            ReviewedQuestionProgress reviewedQuestionProgress = list.get(i);
            // 获取试题总份数
            Integer questionIndex = reviewedQuestionProgress.getQuestionIndex();
            QueryWrapper<Reviewed> wrapper = new QueryWrapper<>();
            wrapper.eq("paper_id", examinationPaperId);
            wrapper.eq("question_index", questionIndex);
            Reviewed reviewed = reviewedDao.selectOne(wrapper);
            String studentStatus = reviewed.getStudentStatus();
            String[] status = studentStatus.split(",");
            // 计算试题的进度
            List<Integer> reviewedNumber = reviewedQuestionProgress.getReviewedNumber();
            Integer nowNumber = reviewedNumber.get(reviewedNumber.size() - 1);
            // 阅卷进度
            reviewedProgress = 1.0 * nowNumber / status.length;
            // 阅卷速度（题每小时）
            Integer lastNumber = reviewedNumber.get(reviewedNumber.size() - 2);
            reviewedSpeed = (long) (nowNumber - lastNumber);
            // 预计完成时间
            if (reviewedSpeed == 0) {
                estimatedTime = new Date(System.currentTimeMillis()
                        + (long) (status.length - nowNumber) * 60 * 60 * 1000);
            } else {
                estimatedTime = new Date(System.currentTimeMillis()
                        + (long) ((status.length - nowNumber) / reviewedSpeed * 60 * 60 * 1000));
            }

            ReviewedQuestionProgressResponse questionProgressResponse = new ReviewedQuestionProgressResponse();
            questionProgressResponse.setQuestionIndex(questionIndex);
            questionProgressResponse.setReviewedProgress(reviewedProgress);
            questionProgressResponse.setEstimatedTime(estimatedTime);
            reviewedQuestionProgressList.add(questionProgressResponse);
        }

        return reviewedQuestionProgressList;

    }

    @Override
    public ReviewedPaperProgressResponse getReviewedProgress(Integer examinationPaperId) {

        // 获取该试卷的进度信息
        List<ReviewedQuestionProgress> list = (List<ReviewedQuestionProgress>) redisService.get(String.valueOf(examinationPaperId));

        // 阅卷进度
        Double reviewedProgress = null;
        // 阅卷速度（题每小时）
        Long reviewedSpeed = null;
        // 预计完成时间
        Date estimatedTime = null;
        // 阅卷进度和
        double totalProgress = 0;
        // 最晚预计完成时间
        Date latestTime = new Date();

        // 获取所有试题的进度
        List<ReviewedQuestionProgressResponse> reviewedQuestionProgressList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            ReviewedQuestionProgress reviewedQuestionProgress = list.get(i);
            // 获取试题总份数
            Integer questionIndex = reviewedQuestionProgress.getQuestionIndex();
            QueryWrapper<Reviewed> wrapper = new QueryWrapper<>();
            wrapper.eq("paper_id", examinationPaperId);
            wrapper.eq("question_index", questionIndex);
            Reviewed reviewed = reviewedDao.selectOne(wrapper);
            String studentStatus = reviewed.getStudentStatus();
            String[] status = studentStatus.split(",");
            // 计算试题的进度
            List<Integer> reviewedNumber = reviewedQuestionProgress.getReviewedNumber();
            Integer nowNumber = reviewedNumber.get(reviewedNumber.size() - 1);
            // 阅卷进度
            reviewedProgress = 1.0 * nowNumber / status.length;
            totalProgress += reviewedProgress;
            // 阅卷速度（题每小时）
            Integer lastNumber = reviewedNumber.get(reviewedNumber.size() - 2);
            reviewedSpeed = (long) (nowNumber - lastNumber);
            // 预计完成时间
            if (reviewedSpeed == 0) {
                estimatedTime = new Date(System.currentTimeMillis()
                        + (long) (status.length - nowNumber) * 60 * 60 * 1000);
            } else {
                estimatedTime = new Date(System.currentTimeMillis()
                        + (long) ((status.length - nowNumber) / reviewedSpeed * 60 * 60 * 1000));
            }
            // 最晚预计完成时间
            if (estimatedTime.after(latestTime)) {
                latestTime = estimatedTime;
            }

            ReviewedQuestionProgressResponse questionProgressResponse = new ReviewedQuestionProgressResponse();
            questionProgressResponse.setQuestionIndex(questionIndex);
            questionProgressResponse.setReviewedProgress(reviewedProgress);
            questionProgressResponse.setEstimatedTime(estimatedTime);
            questionProgressResponse.setQuestionId(reviewed.getQuestionId());
            reviewedQuestionProgressList.add(questionProgressResponse);
        }

        ReviewedPaperProgressResponse response = new ReviewedPaperProgressResponse();
        response.setPaperId(examinationPaperId);
        // 阅卷总进度
        response.setReviewedProgress(totalProgress / list.size());
        response.setEstimatedTime(latestTime);
        response.setReviewedQuestionProgressList(reviewedQuestionProgressList);

        return response;
    }

    /**
     * 每一小时执行一次
     */
    @Scheduled(cron = "0 0 0/1 * * ?")
    // @Scheduled(cron = " 0 0/1 * * * ? ")
    public void reviewedProgress() {
        System.out.println("进入reviewedProgress方法");
        // 查询所有批阅中的试卷
        QueryWrapper<ExaminationPaper> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 5);
        List<ExaminationPaper> paperList = examinationPaperDao.selectList(wrapper);

        QueryWrapper<Reviewed> wrapper1 = new QueryWrapper<>();
        for (int i = 0; i < paperList.size(); i++) {
            // 获取该试卷中的所有题
            Integer paperId = paperList.get(i).getId();
            wrapper1.eq("paper_id", paperId);
            List<Reviewed> reviewedList = reviewedDao.selectList(wrapper1);

            // 判断redis中，是否已存在该试卷信息
            List<ReviewedQuestionProgress> list = null;
            boolean flag = false;
            if (redisService.hasKey(String.valueOf(paperId))) {
                list = (List<ReviewedQuestionProgress>) redisService.get(String.valueOf(paperId));
                flag = true;
            }

            // 将每道题当前的批阅总数存入redis
            List<ReviewedQuestionProgress> questions = new ArrayList<>();
            for (int j = 0; j < reviewedList.size(); j++) {
                Reviewed reviewed = reviewedList.get(j);
                Integer questionIndex = reviewed.getQuestionIndex();
                String studentStatus = reviewed.getStudentStatus();
                String[] status = studentStatus.split(",");
                int reviewedNumber = 0;
                for (int k = 0; k < status.length; k++) {
                    if ("1".equals(status[k])) {
                        reviewedNumber++;
                    }
                }

                ReviewedQuestionProgress reviewedQuestionProgress = new ReviewedQuestionProgress();
                reviewedQuestionProgress.setQuestionIndex(questionIndex);

                // 查询每个教师的批阅量
                List<TeacherProgress> list2 = null;
                if (flag) {
                    ReviewedQuestionProgress questionProgress = list.get(j);
                    list2 = questionProgress.getTeacherProgressList();
                }

                // 获取教师进度列表
                List<TeacherProgress> teacherProgressList = new ArrayList<>();

                QueryWrapper<TeacherReviewed> wrapper2 = new QueryWrapper<>();
                wrapper2.eq("paper_id", paperId);
                wrapper2.eq("question_index", questionIndex);
                List<TeacherReviewed> teacherReviewedList = teacherReviewedDao.selectList(wrapper2);

                TeacherProgress teacherProgress1 = null;
                for (int k = 0; k < teacherReviewedList.size(); k++) {
                    teacherProgress1 = new TeacherProgress();

                    TeacherReviewed teacherReviewed = teacherReviewedList.get(k);
                    // 获取教师账号和当前已批阅量
                    String teacherAccount = teacherReviewed.getTeacherAccount();
                    Integer reviewedNumber1 = teacherReviewed.getReviewedNumber();

                    List<Integer> teacherReviewedNumber = null;
                    if (flag) {
                        for (int l = 0; l < list2.size(); l++) {
                            TeacherProgress teacherProgress = list2.get(l);
                            if (teacherProgress.getTeacherAccount().equals(teacherAccount)) {
                                teacherReviewedNumber = teacherProgress.teacherReviewedNumber;
                                teacherReviewedNumber.add(reviewedNumber1);
                                break;
                            }
                        }
                    }
                    if (teacherReviewedNumber == null) {
                        teacherReviewedNumber = new ArrayList<>();
                        for (int l = 0; l < 5; l++) {
                            teacherReviewedNumber.add(0);
                        }
                    }

                    teacherProgress1.setTeacherAccount(teacherAccount);
                    teacherProgress1.setTeacherReviewedNumber(teacherReviewedNumber);
                    teacherProgressList.add(teacherProgress1);
                }

                reviewedQuestionProgress.setTeacherProgressList(teacherProgressList);

                // 查询总批阅量
                List<Integer> list1 = null;
                if (flag) {
                    ReviewedQuestionProgress questionProgress = list.get(j);
                    list1 = questionProgress.getReviewedNumber();
                } else {
                    list1 = new ArrayList<>();
                }

                list1.add(reviewedNumber);
                reviewedQuestionProgress.setReviewedNumber(list1);

                questions.add(reviewedQuestionProgress);

            }
            redisService.set(String.valueOf(paperId), questions, 60 * 60 * 24 * 10L);
        }

    }

    @Data
    public static class ReviewedQuestionProgress {
        private Integer questionIndex;
        private List<Integer> reviewedNumber;
        private List<TeacherProgress> teacherProgressList;
    }

    @Data
    public static class TeacherProgress {
        private String teacherAccount;
        private List<Integer> teacherReviewedNumber;
    }

}
